/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.edit.handlers;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.Lifeline;

import com.cea.papyrus.core.utils.LookForElement;
import com.cea.papyrus.diagram.sequence.sedi.edit.command.AnalyseCoveredByCommand;
import com.cea.papyrus.diagram.sequence.sedi.edit.command.SelectPartCommand;
import com.cea.papyrus.diagram.sequence.sedi.model.command.CoveredByCommand;
import com.cea.papyrus.diagram.sequence.sedi.model.command.CreateGraphicalElementCommand;
import com.cea.papyrus.diagram.sequence.sedi.model.command.CreateLifelineCommand;
import com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;

/**
 * Handles creation of Lifelines.
 * <p>
 * This handler is used from FrameLayoutPolicy.
 * </p>
 * 
 * @author frankd@ifi.uio.no
 */
public class LifelineCreationHandler implements CreationHandler {

	public final EditPolicy hostPolicy;

	public LifelineCreationHandler(final EditPolicy hostPolicy) {
		this.hostPolicy = hostPolicy;
	}

	@SuppressWarnings("unchecked")
	public Command[] getCreateCommands(final CreateRequest request) {

		final EditPart host = hostPolicy.getHost();
		final GraphNode interactionView = (GraphNode) host.getModel();

		// SetBoundsHintCommand [SeDi]
		// Registers a Bounds hint that can be used when the
		// SeDi GraphcialElement is created. (This command is created
		// direcly by the EditPolicy.)
		// CreateLifelineCommand [UML]
		// Creates the UML Lifeline and adds it to the UML interaction
		// When the command is executed, a GraphicalElement will be
		// created in response to the notification. This creation will consume
		// the Bounds hint set previously
		// AnalyseCoveredByCommand [SeDi]
		// Analyses the diagram and detects any fragments covering the
		// new lifeline. The result is input to the next command:
		// CoveredByCommand [UML]
		// Sets the Lifeline's CoveredBy attribute.

		final CreateLifelineCommand createCmd = new CreateLifelineCommand();
		createCmd.setInteraction(ModelUtil
				.<Interaction> getSemantic(interactionView));

		final AnalyseCoveredByCommand analyseCoveredCmd = new AnalyseCoveredByCommand();
		analyseCoveredCmd.setEditPart(hostPolicy.getHost());

		final CoveredByCommand coverCmd = new CoveredByCommand();

		final SelectPartCommand selectCmd = new SelectPartCommand();
		selectCmd.setAnyEditPart(hostPolicy.getHost().getRoot());
		selectCmd.setSelectForEdit(true);

		final CreateGraphicalElementCommand createGECmd = new CreateGraphicalElementCommand();
		createGECmd.setAnyEditPart(hostPolicy.getHost());
		createGECmd.setParentGE(interactionView);

		Command glueGE = new Command() {
			@Override
			public void execute() {
				createGECmd.setElement(createCmd.getLifeline());
			}
		};

		Command glue1 = new Command() {
			@SuppressWarnings("unchecked")
			public void execute() {
				final Diagram diagram = LookForElement
						.getDiagram(interactionView);
				final Lifeline lifeline = createCmd.getLifeline();
				analyseCoveredCmd.setLifelineView(ModelUtil.getGraphNode(
						lifeline, diagram));
				selectCmd.setTarget(lifeline);
			}
		};

		Command glue2 = new Command() {
			public void execute() {
				coverCmd.setLifeline(createCmd.getLifeline());
				coverCmd.setCoveredBy(analyseCoveredCmd.getCoveredBy());
			}
		};

		return new Command[] { createCmd, glueGE, createGECmd, glue1,
				analyseCoveredCmd, glue2, coverCmd, selectCmd };
	}
}
